/*
 * Ethan Levine
 * 
 * The contents of this file are subject to the GNU General Public
 * License (GPL) v2.  The full contents of this license can be
 * found at Mathma's website, http://www.codeplex.com/mathma/license
 */
package mathma.core.form;

import mathma.core.expr.Expression;
import mathma.core.expr.VariableMapping;

import mathma.core.value.Value;
import mathma.core.value.ValueType;

import java.util.ArrayList;
import java.util.List;

/**
 * @since 0.1.0
 * @author Ethan Levine
 */
public abstract class BinaryExpression<E extends Value, O extends Value>
        extends FormulaicExpression<E, O> {

    private final Expression<O> firstOperand;
    private final Expression<O> secondOperand;

    protected BinaryExpression(ValueType<E> type, Expression<O> firstOperand,
            Expression<O> secondOperand) {
        super(type);
        this.firstOperand = firstOperand;
        this.secondOperand = secondOperand;
    }

    public Expression<O> getFirstOperand() {
        return firstOperand;
    }

    public Expression<O> getSecondOperand() {
        return secondOperand;
    }
    
    @Override
    public List<Expression<O>> getOperands() {
        List<Expression<O>> operands = new ArrayList<Expression<O>>();
        operands.add(firstOperand);
        operands.add(secondOperand);
        return operands;
    }
    
    @Override
    public BinaryExpression<E, O> newInstance(List<Expression<O>> operands) {
        if (operands.size() == 2) {
            return newBinaryExpression(operands.get(0), operands.get(1));
        } else {
            throw new IllegalArgumentException(
                    "BinaryExpression can only take two operands.");
        }
    }
    
    abstract public BinaryExpression<E, O> newBinaryExpression(
            Expression<O> firstExpr, Expression<O> secondExpr);
}